﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Data;
using System.Windows;
using System.Windows.Media.Animation;

namespace TouchUmlUI
{
    public class AssociationHint : Canvas
    {
        private enum AlphaAnimation { VISIBLE = 1, INVISIBLE = -1, STOP = 0 }        

        private AlphaAnimation alphaAnimation = AlphaAnimation.STOP;
        private TextBox labelBottom;
        private TextBox labelTop;
        private double alpha = 0.0f;
        private System.Windows.Forms.Timer Clock;
        private static double alphaDelta = 0.06;                
        private HoverButton clearButton;
        private HoverButton arrowButton;
        private HoverButton quadButton;
        private HoverButton quadFullButton;
        private AssociationObj associationObj;
        private AssociationObj.AssociactionDirection dir;
        private Canvas bg = new Canvas();
        private AssociationObj.ConnectionPoint connectionPoint;        

        public void setConnectionPoint(AssociationObj.ConnectionPoint connectionPoint)
        {
            this.connectionPoint = connectionPoint;
        }
       

        private void setModelEnding(ModelUML.AsocjacjaUML.EndTypeEnum typeModel)
        {
            ModelUML.AsocjacjaUML modelAssociation = (ModelUML.AsocjacjaUML)((Diagram.Asocjacja)associationObj.guml.obj_uml).element;
            if (dir == AssociationObj.AssociactionDirection.FROM)
            {
                ((Diagram.Asocjacja)associationObj.guml.obj_uml)[0].EndType = typeModel;                                    
            }
            else if (dir == AssociationObj.AssociactionDirection.TO)
            {
                ((Diagram.Asocjacja)associationObj.guml.obj_uml)[1].EndType = typeModel; 
            }
        }

        public void chosenAssociacionClick(object sender, RoutedEventArgs e)
        {
            HoverButton but = (HoverButton)sender;
            ModelUML.AsocjacjaUML.EndTypeEnum shape = (ModelUML.AsocjacjaUML.EndTypeEnum)but.Tag;
            setModelEnding(shape);            
            associationObj.updateEndings(true);
            e.Handled = true;
        }

        public bool IsMouseOver()
        {
            bool ret = bg.IsMouseOver | labelBottom.IsMouseOver | labelTop.IsMouseOver;
            ret = ret | clearButton.IsMouseOver | arrowButton.IsMouseOver;
            ret = ret | quadButton.IsMouseOver | quadFullButton.IsMouseOver;            
            return ret;
        }

        public void Timer_Tick(object sender, EventArgs eArgs)
        {
            if (alphaAnimation != AlphaAnimation.INVISIBLE)
            {
                if (this.Opacity > 0.5)
                {
                    if (this.IsMouseOver() == false)
                    {
                        focusLost(sender, null);
                    }
                }
            }
            if (alphaAnimation == AlphaAnimation.STOP) return;
            this.Opacity += (alphaDelta * (int)alphaAnimation);
            if (alphaAnimation == AlphaAnimation.INVISIBLE)
            {
                if (this.Opacity <= alphaDelta)
                {
                    this.Opacity = 0.0f;
                    this.Visibility = Visibility.Hidden;
                    alphaAnimation = AlphaAnimation.STOP;                    
                }
            }
            else if (alphaAnimation == AlphaAnimation.VISIBLE)
            {
                if (this.Opacity >= 1.0f - alphaDelta)
                {
                    alphaAnimation = AlphaAnimation.STOP;                    
                }
            }
        }

        public void setDirection(AssociationObj.AssociactionDirection adir)
        {
            this.dir = adir;
        }

        public void setPosition(double px, double py)
        {
            InkCanvas.SetLeft(this, px);
            InkCanvas.SetTop(this, py);            
            
            HoverButton[] tab = new HoverButton[5];
            tab[0] = clearButton;
            tab[1] = arrowButton;            
            tab[2] = quadButton;
            tab[3] = quadFullButton;
            double angle = 0;
            double delta = Math.PI / 2.98;
            double radius = 70;
            if (connectionPoint == AssociationObj.ConnectionPoint.WEST)
            {
                bg.Width = 120;
                bg.Height = 180;
                Canvas.SetLeft(bg, px - 70);
                Canvas.SetTop(bg, py - 70);
                px = px - 42;
                for (int i = 0; i < 4; i++)
                {
                    double dx = px + Math.Sin(angle - i * delta) * radius;
                    double dy = py + Math.Cos(angle - i * delta) * radius;

                    tab[i].setCanvasPosition(dx, dy);
                }
                Canvas.SetLeft(labelTop, px-30);
                Canvas.SetTop(labelTop, py-12);
                Canvas.SetLeft(labelBottom, px-30);
                Canvas.SetTop(labelBottom, py + 30);
            }
            else if (connectionPoint == AssociationObj.ConnectionPoint.EAST)
            {
                bg.Width = 120;
                bg.Height = 180;
                Canvas.SetLeft(bg, px-10);
                Canvas.SetTop(bg, py - 70);
                px += 3;
                for (int i = 0; i < 4; i++)
                {
                    double dx = px + Math.Sin(angle + i * delta) * radius;
                    double dy = py + Math.Cos(angle + i * delta) * radius;

                    tab[i].setCanvasPosition(dx, dy);
                }
                Canvas.SetLeft(labelTop, px-5);
                Canvas.SetTop(labelTop, py-10);
                Canvas.SetLeft(labelBottom, px-5);
                Canvas.SetTop(labelBottom,py + 28);
            }
            else if (connectionPoint == AssociationObj.ConnectionPoint.SOUTH)
            {                                
                bg.Width = 180;
                bg.Height = 120;
                Canvas.SetLeft(bg, px - 70);
                Canvas.SetTop(bg, py - 10);
                angle = - delta * 7.453;
                for (int i = 0; i < 4; i++)
                {
                    double dx = px + Math.Sin(angle + i * delta) * radius;
                    double dy = py + Math.Cos(angle + i * delta) * radius;

                    tab[i].setCanvasPosition(dx, dy);
                }                
            }
            else if (connectionPoint == AssociationObj.ConnectionPoint.NORTH)
            {                
                bg.Width = 180;
                bg.Height = 120;
                Canvas.SetLeft(bg, px - 70);
                Canvas.SetTop(bg, py - 73);
                angle = delta * 7.437;
                py = py - 43;
                for (int i = 0; i < 4; i++)
                {
                    double dx = px + Math.Sin(angle + i * delta) * radius;
                    double dy = py + Math.Cos(angle + i * delta) * radius;

                    tab[i].setCanvasPosition(dx, dy);
                }
            }
        }

        public void setShowing(bool aarg)
        {
            System.Console.WriteLine("setShowing(" + aarg + ")");
            alphaAnimation = AlphaAnimation.STOP;
            Clock.Stop();
            if (aarg)
            {                             
                if (alphaAnimation != AlphaAnimation.VISIBLE)
                {
                    alphaAnimation = AlphaAnimation.VISIBLE;
                    this.Visibility = Visibility.Visible;
                    if (Clock.Enabled == false)
                    {     
                        Clock.Start();
                    }
                }
            }
            else
            {
                if (alphaAnimation != AlphaAnimation.INVISIBLE)
                {
                    alphaAnimation = AlphaAnimation.INVISIBLE;
                    if (Clock.Enabled == false)
                    {
                        Clock.Start();
                    }
                }
            }
        }

        public void focusLost(object sender, RoutedEventArgs e)
        {
            if (alphaAnimation != AlphaAnimation.INVISIBLE)
            {
                alphaAnimation = AlphaAnimation.INVISIBLE;
                Clock.Start();
            }
        }

        public void focusGained(object sender, RoutedEventArgs e)
        {
            if (alphaAnimation != AlphaAnimation.VISIBLE)
            {
                alphaAnimation = AlphaAnimation.VISIBLE;
                Clock.Start();
            }
            /*this.Opacity = 1;
            Clock.Stop();
            alphaAnimation = AlphaAnimation.STOP;*/
        }

        public AssociationHint(AssociationObj aObj,double px,double py)
        {
            bg.Width = 120;
            bg.Height = 180;
            bg.Opacity = 0.01;
            bg.Background = System.Windows.Media.Brushes.White;            
            this.Children.Add(bg);
            this.associationObj = aObj;
            clearButton = new HoverButton("ikony\\icon_asocclear.png", "ikony\\icon_asocclearhover.png", 40, 40);
            arrowButton = new HoverButton("ikony\\icon_arrow.png", "ikony\\icon_arrowhover.png", 40, 40);            
            quadButton = new HoverButton("ikony\\icon_quad.png", "ikony\\icon_quadhover.png", 40, 40);
            quadFullButton = new HoverButton("ikony\\icon_quadfull.png", "ikony\\icon_quadfullhover.png", 40, 40);            
            this.Visibility = Visibility.Hidden;
            labelTop = new TextBox();
            labelBottom = new TextBox();
            /*labelTop.LostFocus += focusLost;
            labelBottom.LostFocus += focusLost;
            labelTop.GotFocus += focusGained;
            labelBottom.GotFocus += focusGained;*/
            labelTop.Width = 75;
            labelBottom.Width = 75;
            labelTop.BorderBrush = labelBottom.BorderBrush = System.Windows.Media.Brushes.Transparent;
            labelTop.Opacity = 0.9;
            labelBottom.Opacity = 0.9;
           // this.Children.Add(labelTop);
            //this.Children.Add(labelBottom);
            this.Opacity = alpha;
            Clock = new System.Windows.Forms.Timer();
            Clock.Interval = 10;
            Clock.Tick += new EventHandler(Timer_Tick);
            Clock.Stop();
            clearButton.MouseDown += chosenAssociacionClick;
            arrowButton.MouseDown += chosenAssociacionClick;            
            quadButton.MouseDown += chosenAssociacionClick;
            quadFullButton.MouseDown += chosenAssociacionClick;
            clearButton.Tag = ModelUML.AsocjacjaUML.EndTypeEnum.brak;
            arrowButton.Tag = ModelUML.AsocjacjaUML.EndTypeEnum.generalizacja;
            quadButton.Tag = ModelUML.AsocjacjaUML.EndTypeEnum.agregacja;
            quadFullButton.Tag = ModelUML.AsocjacjaUML.EndTypeEnum.kompozycja;
            this.Children.Add(clearButton);
            this.Children.Add(arrowButton);            
            this.Children.Add(quadButton);
            this.Children.Add(quadFullButton);            
            bg.MouseEnter += focusGained;            
            setPosition(px, py);
        }

    }
    
}
